@tool
class_name BaseRoom
extends Node2D

@export var room_id:int
@export var room_depth:int
@export var room_size:Vector2
@export var room_type:GameEnum.RoomType = GameEnum.RoomType.NullRoom
@export var layers_node:Node2D
@export var layers:Array[TileMapLayer]
@export var rule_tile_config:RuleTileConfig
# 开启生成Enemy的最大怪物数量
@export var start_spawn_task_max_enemy_amount:int = 0
@export var birth_area:SpawnArea
@export var areas:Array[SpawnArea]
var cur_room_status:GameEnum.RoomStatus
var inited:bool = false
var cur_enemies:Array = []
var cur_items:Array = []
var cur_valid_spawn_task_index:int = 0
var cur_room_tile_type_dict:Dictionary = {}
var _room_tile_color_dict:Dictionary = {}
var _spawn_task_tween:Tween = null

signal on_enemey_amount_changed(amount:int)

func init_room():
	paint_room()
	on_enemey_amount_changed.connect(check_enemy_amount)
	# TODO 初始化玩家及其随从
	cur_room_status = GameEnum.RoomStatus.Arrived
	# 开启生成任务
	start_spawn_task()
func get_birth_pos() -> Vector2:
	if birth_area:
		var spawn_pos = birth_area.get_spawn_point(GamePlayerSystem.cur_player,self)
		if spawn_pos:
			return spawn_pos + global_position
		else:
			printerr("没法找到用于生成玩家的位置！")
	return global_position
func get_valid_pos() -> Array[Vector2]:
	return []
func get_tile_type(layer:int,coords) -> GameEnum.RoomTileType:
	if cur_room_tile_type_dict.has(layer):
		for room_tile_type in cur_room_tile_type_dict[layer]:
			var coords_arr:Array = cur_room_tile_type_dict[layer][room_tile_type]
			if coords_arr.find(coords):
				return room_tile_type
		return GameEnum.RoomTileType.Null
	else:
		return GameEnum.RoomTileType.Null
	
func get_room_tile_type(layer:TileMapLayer,coords:Vector2i) -> GameEnum.RoomTileType:
	var room_tile_type = GameEnum.RoomTileType.Undefind
	for rule_tile in rule_tile_config.rule_tiles:
		for data in rule_tile.rule_tile_datas:
			if data.check_is_match_rule(layers,coords):
				room_tile_type = rule_tile.room_tile_type
				return room_tile_type
	return room_tile_type

func get_room_tile_color(room_tile_type:GameEnum.RoomTileType) -> Color:
	if _room_tile_color_dict.is_empty():
		for item in rule_tile_config.room_tile_colors:
			_room_tile_color_dict[item.room_tile_type] = item.debug_color
	return _room_tile_color_dict[room_tile_type] if _room_tile_color_dict[room_tile_type] else Color(1,1,1,0)

func paint_room():
	GameManager.rng_fixed_seed()
	update_room_tile()
	update_room_GO()
	update_tile_type_dict()
	place_all_props()
	bake_all_navigation_polygen()
	update_mini_map()
	GameManager.rng_randomize()
func update_room_tile():
	# TODO 根据地图信息替换地图中的可替换Tile
	pass
func update_room_GO():
	# TODO 根据地图信息替换地图中的可替换物品
	pass
func update_tile_type_dict():
	layers.clear()
	for child in layers_node.get_children():
		if child is TileMapLayer:
			layers.append(child)
	for layer in layers:
		if not cur_room_tile_type_dict.has(layer.name):
			cur_room_tile_type_dict[layer.name] = {}
		for coords in layer.get_used_cells():
			var room_tile_type = get_room_tile_type(layer,coords)
			if not cur_room_tile_type_dict[layer.name].has(room_tile_type):
				cur_room_tile_type_dict[layer.name][room_tile_type] = []
			cur_room_tile_type_dict[layer.name][room_tile_type].append(coords)
func update_mini_map():
	# TODO 更新小地图
	pass
func place_all_props():
	# TODO 放置所有物品
	pass
func bake_all_navigation_polygen():
	for child in get_children():
		if child is NavigationRegion2D:
			child.bake_navigation_polygon(true)
func start_spawn_task():
	if not _spawn_task_tween:
		_spawn_task_tween = areas[cur_valid_spawn_task_index].get_spawn_task(self,create_item)
		_spawn_task_tween.tween_callback(func ():
			_spawn_task_tween = null
			cur_valid_spawn_task_index += 1
			if cur_valid_spawn_task_index >= areas.size():
				end_spawn_task()
			else:
				on_enemey_amount_changed.emit(cur_enemies.size())
			)
func end_spawn_task():
	if _spawn_task_tween:
		_spawn_task_tween.kill()
		_spawn_task_tween = null
	cur_valid_spawn_task_index = areas.size() - 1
func check_room_status():
	if cur_room_status == GameEnum.RoomStatus.NotArrived:
		return
	elif cur_room_status == GameEnum.RoomStatus.Arrived:
		if check_room_end():
			cur_room_status = GameEnum.RoomStatus.End
			destroy_room()
func check_room_end() -> bool:
	# 检查还有无敌对阵营的Enemy
	if cur_valid_spawn_task_index >= areas.size() and not cur_enemies.any(func (enemy):return enemy.get_component_by_name("CampComponent").cur_camp == GameEnum.Camp.Hostile):
		return true
	return false
func destroy_room():
	on_enemey_amount_changed.disconnect(check_enemy_amount)
	end_spawn_task()
	queue_free()
func create_item():
	var item = areas[cur_valid_spawn_task_index].get_item().instantiate()
	var spwan_pos = areas[cur_valid_spawn_task_index].get_spawn_point(item,self)
	if spwan_pos:
		item.global_position = global_position + spwan_pos
		add_child(item)
		# TODO 根据item类型初始化
		if item is CharacterEntity:
			item.init()
		add_item(item)
	else:
		printerr("物体{"+item.name+"}生成失败：没法找到可用的生成位置！")
func add_item(item):
	var is_enemy = item is CharacterEntity
	if is_enemy:
		cur_enemies.append(item)
		on_enemey_amount_changed.emit(cur_enemies.size())
	else:
		cur_items.append(item)
	pass
func remove_enemy(enemy):
	cur_enemies.erase(enemy)
	on_enemey_amount_changed.emit(cur_enemies.size())
func check_enemy_amount(amount:int):
	if amount <= start_spawn_task_max_enemy_amount and not _spawn_task_tween:
		start_spawn_task()

func _draw() -> void:
	for area in areas:
		if area.spawn_area_type == GameEnum.SpawnAreaType.Circle:
			draw_arc(global_position + area.center,area.radius,0,TAU,30,Color.RED)
		elif area.spawn_area_type == GameEnum.SpawnAreaType.Rectangle:
			draw_rect(Rect2(global_position + area.center, area.size),Color.BLUE)
